﻿@using System.Text.RegularExpressions;
@using Syncfusion.Blazor.Navigations;

@namespace BlazorDemos.Shared
@implements IDisposable;

@inject IJSRuntime JsRuntime;
@inject SampleService SampleService;

@if (!isSourceCodeRequired)
{
<div class='sb-tab-content'>
    <span>Loading...</span>
</div> }
else
{
<div class='sb-source-section'>
    <SfTab ID='sb-source-tab' Items="@sourceCodeItems" HeaderPlacement="@HeaderPosition.Bottom" @bind-SelectedItem="tabSelectedIndex">
        <TabEvents Selected="OnSourceClicked"></TabEvents>
    </SfTab>
</div>
}


@code {
    private List<TabItem> sourceCodeItems;
    private string sourceCode { get; set; }
    private string fileName { get; set; }
    private bool isSourceCodeRequired { get; set; }
    private int tabSelectedIndex { get; set; }

    // Source code tab selected event handler.
    private async Task OnSourceClicked(SelectEventArgs args)
    {
        string response = string.Empty;
        await this.GetSourceData((int)args.SelectedIndex);
    }

    private async Task GetSourceData(int index)
    {
        await InvokeAsync(() =>
        {
            sourceCode = string.Empty;
            fileName = string.Empty;
            string directory = SampleService.SampleInfo.Directory;
            if (SampleService.SampleInfo.SourceFiles.Count > index && SampleService.SampleInfo.Directory != null)
            {
                fileName = SampleService.SampleInfo.SourceFiles[index].FileName;
                try
                {
                    sourceCode = System.IO.File.ReadAllText("Pages/" + directory + "/" + fileName);
                }
                catch
                {
                    if (directory.LastIndexOf("/") > 0)
                    {
                        directory = directory.Substring(0, directory.LastIndexOf("/"));
                    }

                    sourceCode = System.IO.File.ReadAllText("Pages/" + directory + "/" + fileName);
                }
            }
            else
            {
                fileName = SampleService.SampleInfo.FileName;
                sourceCode = System.IO.File.ReadAllText("Pages/" + directory + "/" + fileName);
            }
            sourceCode = this.FormatSourceCode(sourceCode);
        });
        await Task.Delay(1000);
        this.isSourceCodeRequired = true;
    }

    private string RemoveString(string comments, string startTag, string endTag)
    {
        int StartIndex = comments.IndexOf(startTag);
        if (StartIndex > 0)
        {
            int EndIndex = comments.IndexOf(endTag) + endTag.Length;
            string Content = comments.Substring(StartIndex, EndIndex - StartIndex);
            return comments.Replace(Content, string.Empty);
        }
        else
        {
            return comments;
        }
    }

    private string FormatSourceCode(string response)
    {
        response = RemoveString(response, "<SampleDescription>", "</SampleDescription>");
        response = RemoveString(response, "<ActionDescription>", "</ActionDescription>");
        response = response.Replace("<", "&lt;");
        response = response.Replace(">", "&gt;");
        while (response.IndexOf("@*Hidden:Lines*@") > -1)
        {
            response = RemoveString(response, "@*Hidden:Lines*@", "@*End:Hidden*@");
        }
        response = Regex.Replace(response, @"^(?:[\t ]*(?:\r?\n|\r))+", string.Empty, RegexOptions.Multiline);

        return response;
    }

    /// <summary>
    /// Renders the dynamic source code tab for showcase the source codes.
    /// </summary>
    /// <param name="args">Arguments used to render the dynamic tab items.</param>
    public async Task OnSourceTabSelected(SelectEventArgs args)
    {
        sourceCodeItems = new List<TabItem>();
        if (args == null || (args != null && args.SelectedIndex == 1))
        {
            if (SampleService.SampleInfo.SourceFiles.Count != 0)
            {
                for (var i = 0; i < SampleService.SampleInfo.SourceFiles.Count; i++)
                {
#pragma warning disable
                    sourceCodeItems.Add(
                    new TabItem()
                    {
                        Header = new TabHeader() { Text = SampleService.SampleInfo.SourceFiles[i].FileName },
                        ContentTemplate =@<pre class='sb-src-code'><code></code></pre>
                        
                    });
#pragma warning restore
                }
                await this.GetSourceData(0);
            }
            else
            {
                sourceCodeItems = new List<TabItem>() {
#pragma warning disable
                new TabItem() {
                        Header = new TabHeader() { Text = SampleService.SampleInfo.FileName },
                        ContentTemplate = @<pre id='code' class='sb-src-code'><code></code></pre>
                }};
#pragma warning restore
                await this.GetSourceData(0);
            }
            this.tabSelectedIndex = 0;
            this.StateHasChanged();
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            await this.OnSourceTabSelected(null);
            await JsRuntime.InvokeAsync<Object>("refreshTab", sourceCode, fileName);
        }
        if (this.isSourceCodeRequired)
        {
            this.isSourceCodeRequired = false;
            await JsRuntime.InvokeAsync<Object>("refreshTab", sourceCode, fileName);
        }
    }

    public void Dispose()
    {
        sourceCodeItems = null;
    }
}
